﻿using System.Diagnostics.Contracts;

namespace System.Reactive.Concurrency
{
	[ContractClass(typeof(LocalSchedulerContract))]
	public abstract class LocalScheduler : IScheduler, IStopwatchProvider
	{
		public DateTimeOffset Now
		{
			get
			{
				return default(DateTimeOffset);
			}
		}

		public virtual IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public virtual IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public abstract IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action);

		public virtual IStopwatch StartStopwatch()
		{
			return null;
		}
	}

	[ContractClassFor(typeof(LocalScheduler))]
	internal abstract class LocalSchedulerContract : LocalScheduler
	{
		public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}
	}
}